/**
 * 天气API服务
 * 集成免费天气API获取真实天气数据
 */

interface WeatherApiResponse {
  code: number
  msg: string
  data: {
    city: string
    data: Array<{
      date: string
      temperature: string
      weather: string
      wind: string
      air_quality: string
    }>
  }
}

interface ParsedWeatherData {
  temperature: number
  humidity: number
  pressure: number
  airQuality: number
  uvIndex: number
  lightIntensity: number
  windSpeed: number
  pm25: number
  weather: string
  city: string
}

export class WeatherService {
  private static readonly API_URL = 'https://v2.xxapi.cn/api/weather'
  private static readonly DEFAULT_CITY = '赣州市'
  private static cachedData: ParsedWeatherData | null = null
  private static lastFetchTime = 0
  private static readonly CACHE_DURATION = 10 * 60 * 1000 // 10分钟缓存

  /**
   * 获取天气数据
   */
  static async getWeatherData(city: string = this.DEFAULT_CITY): Promise<ParsedWeatherData> {
    const now = Date.now()
    
    // 如果有缓存且未过期，直接返回缓存数据
    if (this.cachedData && (now - this.lastFetchTime) < this.CACHE_DURATION) {
      return this.cachedData
    }

    try {
      const controller = new AbortController()
      const timeoutId = setTimeout(() => controller.abort(), 5000) // 5秒超时
      
      const response = await fetch(`${this.API_URL}?city=${encodeURIComponent(city)}`, {
        signal: controller.signal,
        headers: {
          'Accept': 'application/json',
        }
      })
      
      clearTimeout(timeoutId)
      
      if (!response.ok) {
        throw new Error(`HTTP ${response.status}: ${response.statusText}`)
      }
      
      const result: WeatherApiResponse = await response.json()
      
      if (result.code === 200 && result.data?.data?.length > 0) {
        const todayData = result.data.data[0] // 获取今天的数据
        const parsedData = this.parseWeatherData(todayData, result.data.city)
        
        // 更新缓存
        this.cachedData = parsedData
        this.lastFetchTime = now
        
        return parsedData
      } else {
        throw new Error(`API返回码: ${result.code}, 消息: ${result.msg}`)
      }
    } catch (error) {
      console.warn('获取天气数据失败，使用模拟数据:', error)
      return this.getFallbackData()
    }
  }

  /**
   * 解析API返回的天气数据
   */
  private static parseWeatherData(apiData: any, city: string): ParsedWeatherData {
    // 解析温度范围 "4-24℃" -> 取中间值
    const tempMatch = apiData.temperature.match(/(-?\d+)-(-?\d+)℃/)
    const minTemp = tempMatch ? parseInt(tempMatch[1]) : 20
    const maxTemp = tempMatch ? parseInt(tempMatch[2]) : 25
    const avgTemp = (minTemp + maxTemp) / 2

    // 解析风力 "北风4-5级" -> 取中间值转换为风速
    const windMatch = apiData.wind.match(/(\d+)-(\d+)级/)
    const windLevel = windMatch ? (parseInt(windMatch[1]) + parseInt(windMatch[2])) / 2 : 3
    const windSpeed = this.windLevelToSpeed(windLevel)

    // 根据空气质量文字转换为数值
    const airQuality = this.airQualityToNumber(apiData.air_quality)

    // 根据天气状况计算其他参数
    const weatherCondition = apiData.weather
    const humidity = this.calculateHumidity(weatherCondition, avgTemp)
    const pressure = this.calculatePressure(avgTemp)
    const uvIndex = this.calculateUVIndex(weatherCondition)
    const lightIntensity = this.calculateLightIntensity(weatherCondition)
    const pm25 = this.calculatePM25(airQuality)

    return {
      temperature: Math.round(avgTemp * 10) / 10,
      humidity: Math.round(humidity),
      pressure: Math.round(pressure),
      airQuality: Math.round(airQuality),
      uvIndex: Math.round(uvIndex * 10) / 10,
      lightIntensity: Math.round(lightIntensity),
      windSpeed: Math.round(windSpeed * 10) / 10,
      pm25: Math.round(pm25),
      weather: weatherCondition,
      city: city
    }
  }

  /**
   * 风力等级转风速 (m/s)
   */
  private static windLevelToSpeed(level: number): number {
    const speedMap: { [key: number]: number } = {
      1: 1.5, 2: 3.5, 3: 5.5, 4: 8.5, 5: 11.5,
      6: 14.5, 7: 17.5, 8: 21, 9: 25, 10: 29
    }
    return speedMap[Math.round(level)] || 5
  }

  /**
   * 空气质量文字转数值
   */
  private static airQualityToNumber(quality: string): number {
    const qualityMap: { [key: string]: number } = {
      '优': 95, '良': 85, '轻度': 65, '中度': 45, '重度': 25, '严重': 10
    }
    
    for (const [key, value] of Object.entries(qualityMap)) {
      if (quality.includes(key)) {
        return value
      }
    }
    return 80 // 默认值
  }

  /**
   * 根据天气状况计算湿度
   */
  private static calculateHumidity(weather: string, temperature: number): number {
    let baseHumidity = 60
    
    if (weather.includes('雨') || weather.includes('雪')) {
      baseHumidity = 85
    } else if (weather.includes('晴')) {
      baseHumidity = 45
    } else if (weather.includes('云') || weather.includes('阴')) {
      baseHumidity = 65
    } else if (weather.includes('雾') || weather.includes('霾')) {
      baseHumidity = 90
    }

    // 温度影响：温度越高，相对湿度可能越低
    const tempAdjustment = (25 - temperature) * 0.5
    
    return Math.max(30, Math.min(95, baseHumidity + tempAdjustment + (Math.random() - 0.5) * 10))
  }

  /**
   * 根据温度计算气压
   */
  private static calculatePressure(temperature: number): number {
    // 标准大气压约1013hPa，温度每升高1度，气压约降低0.1hPa
    const basePressure = 1013
    const tempEffect = (20 - temperature) * 0.1
    return basePressure + tempEffect + (Math.random() - 0.5) * 5
  }

  /**
   * 根据天气状况计算紫外线指数
   */
  private static calculateUVIndex(weather: string): number {
    const hour = new Date().getHours()
    
    // 夜间紫外线为0
    if (hour < 6 || hour > 18) {
      return 0
    }

    let baseUV = 6
    if (weather.includes('晴')) {
      baseUV = 9
    } else if (weather.includes('云')) {
      baseUV = 6
    } else if (weather.includes('阴') || weather.includes('雨') || weather.includes('雪')) {
      baseUV = 3
    }

    // 时间影响：中午最强
    const timeMultiplier = Math.sin((hour - 6) / 12 * Math.PI)
    
    return Math.max(0, baseUV * timeMultiplier + (Math.random() - 0.5) * 2)
  }

  /**
   * 根据天气状况计算光照强度
   */
  private static calculateLightIntensity(weather: string): number {
    const hour = new Date().getHours()
    
    // 夜间光照强度很低
    if (hour < 6 || hour > 18) {
      return Math.random() * 50 // 人工照明
    }

    let baseIntensity = 800
    if (weather.includes('晴')) {
      baseIntensity = 1200
    } else if (weather.includes('云')) {
      baseIntensity = 800
    } else if (weather.includes('阴')) {
      baseIntensity = 500
    } else if (weather.includes('雨') || weather.includes('雪')) {
      baseIntensity = 300
    }

    // 时间影响
    const timeMultiplier = Math.sin((hour - 6) / 12 * Math.PI)
    
    return Math.max(100, baseIntensity * timeMultiplier + (Math.random() - 0.5) * 200)
  }

  /**
   * 根据空气质量计算PM2.5
   */
  private static calculatePM25(airQuality: number): number {
    // 空气质量指数越高，PM2.5越低
    const basePM25 = (100 - airQuality) * 0.8
    return Math.max(5, basePM25 + (Math.random() - 0.5) * 10)
  }

  /**
   * 获取备用数据（API失败时使用）
   */
  private static getFallbackData(): ParsedWeatherData {
    const hour = new Date().getHours()
    return {
      temperature: Math.round((25 + 5 * Math.sin((hour - 13) / 12 * Math.PI) + (Math.random() - 0.5) * 2) * 10) / 10,
      humidity: Math.round(65 + 10 * Math.cos((hour - 13) / 12 * Math.PI) + (Math.random() - 0.5) * 5),
      pressure: Math.round(1013 + Math.sin(hour / 24 * Math.PI * 2) * 3 + (Math.random() - 0.5)),
      airQuality: Math.round(75 + Math.random() * 15),
      uvIndex: hour >= 7 && hour <= 17 ? Math.round(6 + Math.random() * 4) : 0,
      lightIntensity: hour >= 6 && hour <= 18 ? Math.round(700 + Math.random() * 500) : Math.random() * 50,
      windSpeed: Math.round((2 + Math.random() * 4) * 10) / 10,
      pm25: Math.round(25 + Math.random() * 15),
      weather: '多云',
      city: '赣州市'
    }
  }
}
